import React, {
  useState,
  ForwardedRef,
  useImperativeHandle,
  forwardRef,
  useEffect,
} from "react";
import { PlusOutlined } from "@ant-design/icons";
import { Modal, Upload } from "antd";
import type { GetProp, UploadFile, UploadProps } from "antd";
import { changeaddImgState } from "@/store/modules/assStore";
import { useAppSelector, useAppDispatch } from "@/store/hook.ts";
import { uploadImg } from "@/api/api_upload";
type FileType = Parameters<GetProp<UploadProps, "beforeUpload">>[0];

interface ChildMethods {
  handleUpload: () => void;
}

const getBase64 = (file: FileType): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = (error) => reject(error);
  });

const UploadImgX: React.FC = forwardRef(
  (props, ref: ForwardedRef<ChildMethods>) => {
    const addImg = useAppSelector((state) => state.ass.addImg);
    const assInfo = useAppSelector((state) => state.ass.assInfo);
    const isAdd = useAppSelector((state) => state.ass.isAdd);
    const dispatch = useAppDispatch();

    const [previewOpen, setPreviewOpen] = useState(false);
    const [previewImage, setPreviewImage] = useState("");
    const [previewTitle, setPreviewTitle] = useState("");
    const [fileList, setFileList] = useState<UploadFile[]>([]);

    useEffect(() => {
      if (addImg === 0) {
        const img_url = assInfo.img_url_arr.map((url: string) => {
          return {
            type: "image/jpeg",
            url: url,
          };
        });

        setFileList(img_url);
        dispatch(changeaddImgState(1));
      } else if (addImg === 1 && isAdd) {
        setFileList([]);
        dispatch(changeaddImgState(-1));
      }
    }, [addImg, assInfo, isAdd, dispatch]);

    const handleCancel = () => setPreviewOpen(false);

    const handlePreview = async (file: UploadFile) => {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj as FileType);
      }

      setPreviewImage(file.url || (file.preview as string));
      setPreviewOpen(true);
      setPreviewTitle(
        file.name || file.url!.substring(file.url!.lastIndexOf("/") + 1)
      );
    };

    const handleChange: UploadProps["onChange"] = ({ fileList: newFileList }) =>
      setFileList(newFileList);

    const uploadButton = (
      <button style={{ border: 0, background: "none" }} type="button">
        <PlusOutlined />
        <div style={{ marginTop: 8 }}>Upload</div>
      </button>
    );

    const handleUpload = async () => {
      const formData = new FormData();
      fileList.forEach((file) => {
        formData.append(`files`, file.originFileObj as FileType);
      });

      try {
        const img_url_arr: string[] = [];
        //函数定义
        const uploadAndPushImages = async (
          formData: FormData,
          uploadFunction: (
            formData: FormData,
            type: string
          ) => Promise<string[] | undefined>
        ) => {
          //增 删 不变
          fileList.forEach((file) => {
            if (file.url) {
              img_url_arr.push(file.url);
            }
          });
          // console.log(fileList, "FileList");

          const imgUrlArr = (await uploadFunction(formData, props.type))
            ?.img_url;
          if (imgUrlArr) {
            img_url_arr.push(...imgUrlArr);
          }
        };

        await uploadAndPushImages(formData, uploadImg);

        setFileList([]);
        return img_url_arr;
      } catch (err) {
        console.log(err);
        return []; // 处理上传失败的情况
      }
    };

    // 使用 useImperativeHandle 定义暴露给父组件的方法
    useImperativeHandle(ref, () => ({
      handleUpload,
    }));

    return (
      <>
        <Upload
          action="http://127.0.0.1:3001/gpu/uploads"
          listType="picture-card"
          fileList={fileList}
          onPreview={handlePreview}
          onChange={handleChange}
        >
          {fileList.length >= 3 ? null : uploadButton}
        </Upload>
        <Modal
          open={previewOpen}
          title={previewTitle}
          footer={null}
          onCancel={handleCancel}
        >
          <img alt="example" style={{ width: "100%" }} src={previewImage} />
        </Modal>
      </>
    );
  }
);

export default UploadImgX;
